package org.ddd.specification.catalog.collection;

import org.ddd.specification.Specification;
import org.ddd.specification.catalog.AbstractSpecification;

/**
 * Specification that checks if atleast one of the candidate's element satisfies
 * our delegate specification.
 * 
 * @author Jeroen van Schagen
 * @since 22-02-2011
 *
 * @param <T> type of candidate elements being checked
 */
public class AnyElementSpecification<T> extends AbstractSpecification<Iterable<? extends T>> {
    private final Specification<T> delegate;

    /**
     * Construct a new {@link AnyElementSpecification}.
     * @param delegate the delegate specification, used to evaluate each element
     */
    public AnyElementSpecification(Specification<T> delegate) {
        super();
        if (delegate == null) {
            throw new IllegalArgumentException("Delegate specification cannot be null.");
        }
        this.delegate = delegate;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isSatisfiedBy(Iterable<? extends T> candidate) {
        for (T element : candidate) {
            if (delegate.isSatisfiedBy(element)) {
                return true;
            }
        }
        return false;
    }

}
